class Solution(object):
    def containsCycle(self, grid):
        m = len(grid)
        n = len(grid[0])
        used = [[0 for _ in range(n)] for _ in range(m)]

        def dfs(last_x, last_y, x, y):
            for ux, uy in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]:
                if 0 <= ux < m and 0 <= uy < n:
                    if grid[ux][uy] == grid[x][y] and (ux != last_x or uy != last_y):
                        if used[ux][uy]:
                            return True
                        else:
                            used[ux][uy] = 1
                            if dfs(x, y, ux, uy):
                                return True
            return False

        for i in range(m):
            for j in range(n):
                if not used[i][j]:
                    used[i][j] = 1
                    if dfs(i, j, i, j):
                        return True
        return False
